using System;
using System.Collections.Generic;
using CastleSample.Business.Interface;
using CastleSample.Core;
using CastleSample.Entity;

namespace CastleSample.Business.Client
{
    public class BizServiceFactory
    {
        private static IRemoteBizServiceFactory m_RemoteBizServiceFactory = ServiceLocator.Get<IRemoteBizServiceFactory>();
        private static Dictionary<string, IBizService> m_CachedRemoteBizServices = new Dictionary<string, IBizService>();

        public static T GetLocalService<T>() where T : IBizService
        {
            if (UserContext.Current != null && UserContext.Current.LoggedIn && UserContext.Current.OnlineMode)
            {
                LogService.WarnFormat(typeof (BizServiceFactory).FullName, "Online User Request Local Service {0}", typeof (T).Name);
            }
            T service = ServiceLocator.Get<T>();
            if (service != null)
            {
                service.CurrentUserContext = UserContext.Current;
            }
            return service;
        }

        public static T GetRemoteService<T>() where T : IBizService
        {
            if (UserContext.Current != null && UserContext.Current.LoggedIn && !UserContext.Current.OnlineMode)
            {
                LogService.WarnFormat(typeof (BizServiceFactory).FullName, "Offline User Request Remote Service {0}", typeof (T).Name);
            }
            if (m_CachedRemoteBizServices.ContainsKey(typeof (T).FullName))
            {
                return (T) m_CachedRemoteBizServices[typeof (T).FullName];
            }

            T service;
            if (UserContext.Current != null && UserContext.Current.LoggedIn)
            {
                service = m_RemoteBizServiceFactory.GetService<T>(UserContext.Current);
            }
            else
            {
                service = m_RemoteBizServiceFactory.GetService<T>();
            }
            if (service != null)
            {
                m_CachedRemoteBizServices.Add(typeof (T).FullName, service);
            }
            return service;
        }

        public static T GetService<T>() where T : IBizService
        {
            if (typeof (T).IsSubclassOf(typeof (IMembershipBizService)))
            {
                throw new ApplicationException("Use GetLocalService<T> or GetRemoteService<T> instead of GetService<T>");
            }
            if (UserContext.Current == null)
            {
                throw new ApplicationException("Current UserContext is null");
            }
            return UserContext.Current.OnlineMode ? GetRemoteService<T>() : GetLocalService<T>();
        }
    }
}